home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / utilitys / 104 / yaps_c.s < prev    next >
Encoding:
Text File  |  1987-09-20  |  13.7 KB  |  350 lines

  1.    ilabel TOS\TOS.L
  2. ;
  3. ;  Program Equates
  4. gpip      =     0
  5. aer       =     2
  6. len       =     4
  7. head      =     8
  8. tail      =     12
  9. gemdos    =     1
  10. bios      =     13
  11. xbios     =     14
  12. isrb      =    $10
  13. timeo     =     30
  14. keep      =    $31
  15. porta     =     14
  16. portb     =     15
  17. trap13    =    $B4
  18. savptr    =    $4A2
  19. hz_200    =    $4BA
  20. MFP       =    $FFFFFA01
  21. PSG       =    $FFFF8800
  22. ;
  23. ;Start of program for YAPS - Centronics Busy Signal Version
  24. ;
  25.         text
  26. yaps:   bra     ypstrm          ;Branch to temporary segment of program
  27. check:  dc.b    'YAPS_C.PRG'
  28. ;
  29. ; New Trap #13 Handler to intercept Printer Out and Status calls
  30. ;
  31. newtrp: move.l  savptr,A1       ;Save registers, sr, and return address
  32.         move.w  (sp)+,D0        ;  keeping a copy of sr to test for SUPER
  33.         move.w  D0,-(A1)        ;  vs. User mode
  34.         move.l  (sp)+,-(A1)
  35.         movem.l D3-D7/A3-A7,-(A1)
  36.         move.l  A1,savptr       ;Update save area pointer
  37.         btst    #13,D0          ;Get correct stack pointer
  38.         bne     newt10
  39.         move.l  usp,sp
  40. newt10: move.w  (sp),D0         ;Get call number
  41.         cmp.w   #3,D0           ;Check for "Conout"
  42.         bne     newt30
  43.         tst.w   2(sp)           ;If "Conout" then are we dealing with PRN: ?
  44.         bne     newt50
  45.         move.w  4(sp),D1        ;Get character to print and do it!
  46.         bsr     printo          ;jump to print character
  47. newt20: move.l  savptr,A1       ;Restore registers, sr, and return address
  48.         movem.l (A1)+,D3-D7/A3-A7
  49.         move.l  (A1)+,-(sp)
  50.         move.w  (A1)+,-(sp)
  51.         move.l  A1,savptr
  52.         rte
  53. newt30: cmp.w   #8,D0           ;Check for "Constat"
  54.         bne     newt50
  55.         tst.w   2(sp)           ;If "Constat" then are we dealing with PRN: ?
  56.         bne     newt50
  57.         move.w  sr,-(sp)        ;Stop Centronics Irq while testing printer buff
  58.         ori.w   #$0700,sr
  59.         moveq   #-1,D0
  60.         bsr     getptr          ;Check to see if there is room in the
  61.         move.l  tail(A0),D2     ;  Printer Spooler. If so, the printer
  62.         bsr     wrap            ;  must not be busy.
  63.         cmp.l   head(A0),D2
  64.         bne     newt40
  65.         moveq   #0,D0
  66. newt40: move.w  (sp)+,sr        ;Restart Centronics Interrupt
  67.         bra     newt20
  68. newt50: move.l  savptr,A1       ;Restore registers, sr, and return address
  69.         movem.l (A1)+,D3-D7/A3-A7
  70.         move.l  (A1)+,-(sp)
  71.         move.w  (A1)+,-(sp)
  72.         move.l  A1,savptr
  73.         move.l  trpsve,A0       ;Not a Printer call - then just continue
  74.         jmp     (A0)            ;  on...
  75. ;
  76. ; Actual Centronics Interrupt routine
  77. ; plus Printer Spooler out routine
  78. ;
  79. timer:  movem.l D0-D2/A0-A2,-(sp)
  80.         lea     MFP,A1          ;save registers and load pointers
  81. time00: btst    #0,gpip(A1)     ;Check if printer BUSY
  82.         bne     time10
  83.         bsr     getptr          ;Is there anything in buffer to print..
  84.         move.l  head(A0),D2
  85.         cmp.l   tail(A0),D2
  86.         beq     time10
  87.         bsr     wrap            ;Set up pointers to retrieve character
  88.         move.l  (A0),A2         ;  to print.
  89.         move.b  0(A2,D2.l),D1
  90.         bsr     notbus          ;Branch to specialized printing routine
  91.         move.l  D2,head(A0)
  92.         bra     time00
  93. time10: bclr    #0,isrb(A1)     ;Clear interrupt bit
  94.         movem.l (sp)+,D0-D2/A0-A2
  95. timret: rte
  96. ;
  97. ; subroutine to send character to printer buffer OR printer
  98. ;
  99. printo: bsr     getptr          ;Set up pointers
  100.         move.l  head(A0),D2     ;If buffer already contains charcters
  101.         cmp.l   tail(A0),D2     ;  even if printer is now ready, store
  102.         bne     inbuff          ;  any new characters in the buffer!
  103. loop:   btst    #0,(A1)         ;If printer is BUSY, store characters
  104.         bne     inbuff          ;  in buffer.
  105. notbus: move    sr,-(sp)        ;This is the specialized routine to output
  106.         ori     #$0700,sr       ;  characters to a parallel printer. It has
  107.         movem.l D2-D5,-(sp)     ;  been optimized to pulse the strobe for
  108.         lea     PSG,A2          ;  2 microseconds, which is the limit of the
  109.         moveq   #portb,D2       ;  sound chip!
  110.         asl.l   #8,D2           ;Set up D2 to contain the character to print
  111.         add.b   D1,D2           ;  and the sound register to set up.
  112.         moveq   #portb,D5       ;Set up D5 to send a null character to print
  113.         asl.l   #8,D5           ;  and the sound register to set up.
  114.         moveq   #0,D0
  115.         move.b  #7,(A2)         ;Select the correct sound registers
  116.         move.b  (A2),D0
  117.         or.b    #$80,D0
  118.         move.b  #7,(A2)
  119.         move.b  D0,2(A2)
  120.         moveq   #porta,D3       ;Set up D3 to pulse the strobe high
  121.         asl.l   #8,D3
  122.         moveq   #0,D4           ;Set up D4 to pulse the strobe low
  123.         move.b  #porta,(A2)
  124.         move.b  (A2),D4         ;Get the current configuration of Port A
  125.         and.b   #$DF,D4         ;Finish setting up the contents of D3 to
  126.         move.b  D4,D3           ;  pulse the strobe
  127.         or.b    #$20,D4
  128.         movep.w D2,0(A2)        ;These next 4 statements actually write
  129.         movep.w D3,0(A2)        ;  the data to the Printer and pulse the
  130.         move.b  D4,2(A2)        ;  strobe
  131.         movep.w D5,0(A2)
  132.         moveq   #-1,D0          ;Return -1 as success
  133.         movem.l (sp)+,D2-D5
  134.         move    (sp)+,sr
  135.         rts
  136. inbuff: move.l  tail(A0),D2     ;First check to see if there is any more
  137.         bsr     wrap            ;  room in the printer buffer to store
  138.         cmp.l   head(A0),D2     ;  more characters
  139.         beq     inb100
  140. inb010: move.l  (A0),A1         ;If there is room, store the character and
  141.         move.b  D1,0(A1,D2.l)   ;  return -1 as success
  142.         move.l  D2,tail(A0)
  143.         moveq   #-1,D0
  144.         rts
  145. inb100: move.l  hz_200,D0       ;No room, then wait up to 30 seconds for the
  146.         add.l   #timeo*200,D0   ;  printer buffer to be cleared by the
  147. wait:   cmp.l   head(A0),D2     ;  Timer C interrupt
  148.         bne     inb010
  149.         cmp.l   hz_200,D0
  150.         bhi     wait
  151.         moveq   #0,D0           ;No luck, printer down - return 0
  152.         rts
  153. ;
  154. ;Routine to setup pointers
  155. ;
  156. getptr: lea     rec_io,A0
  157.         lea     MFP,A1
  158.         rts
  159. ;
  160. ;Routine to wrap pointers around buffer
  161. ;
  162. wrap:   addq.l  #1,D2
  163.         cmp.l   len(A0),D2
  164.         bcs     nowrap
  165.         moveq   #0,D2
  166. nowrap  rts
  167. ;
  168. ; Data Segment - nonvolatile
  169. ;
  170. rec_io: dc.l    ypstrm
  171. length: dc.l    0
  172.         dc.l    0
  173.         dc.l    0
  174. ;
  175. ; BSS Segment - nonvolatile
  176. ;
  177. trpsve: ds.l    1
  178. ;
  179. ; Temporary Program Start
  180. ;
  181. ypstrm: PRINTLINE tline         ;Show title of program
  182.         bsr     go_sup          ;Enter SUPER mode and test to see if the
  183.         sub.l   A2,A2           ;  Printer Spooler has already been installed
  184.         move.l  trap13(A2),A0
  185.         sub.l   #10,A0          ;Check for title of program in the 10 bytes
  186.         lea     check,A1        ;  preceeding the start of the TRAP #13 handler
  187.         moveq   #7,D1
  188. yps000: cmpm.b  (A1)+,(A0)+
  189.         bne     yps040
  190.         dbra    D1,yps000
  191.         bsr     go_use
  192.         PRINTLINE error5        ;  ask if user wishes to clear buffer,
  193. yps010: CONIN_WE                ;  then end program
  194.         and.b   #$5F,D0
  195.         cmpi.b  #'Y',D0
  196.         bne     yps020
  197.         CONOUT  D0
  198.         bsr     go_sup          ;To clear buffer, must first enter SUPER
  199.         move.w  sr,-(sp)        ;  mode to stop all interrupts, including
  200.         ori.w   #$0700,sr       ;  Centronics Irq.  Then clear the "head"
  201.         sub.l   A1,A1           ;  and "tail" values of pointer to buffer.
  202.         move.l  trap13(A1),A0   ;Set up pointer to "head/tail"
  203.         add.l   #length-newtrp+4,A0
  204.         clr.l   (A0)
  205.         clr.l   4(A0)
  206.         move.w  (sp)+,sr        ;When done, start interrupts, get out of
  207.         bsr     go_use          ;  SUPER mode, and leave.
  208.         TERM
  209. yps020: cmpi.b  #'N',D0
  210.         beq     yps030
  211.         CONOUT  #7
  212.         bra     yps010
  213. yps030: CONOUT  D0
  214.         TERM
  215. yps040: bsr     go_use          ;Restore to user mode
  216.         move.l  4(sp),A0        ;Calculate size of program...
  217.         move.l  4(A0),D7        ;D7 will contain the end of the available TPA
  218.         sub.l   A0,D7           ;  minus the basepage address
  219.         move.l  #$100,D6        ;Size of base page
  220.         add.l   12(A0),D6       ;add TEXT length
  221.         add.l   20(A0),D6       ;add DATA length
  222.         add.l   28(A0),D6       ;add BSS  length
  223.         GETDTA                  ;ASK THE OPERATING SYSTEM FOR OUR FILE NAME
  224.         move.l  D0,A5           ;save address of current DTA
  225.         move.l  #buflen,A4      ;Set up pointer to size of buffer indicator
  226.         SFIRST  attrib,fname
  227.         tst     D0              ;Test for file found
  228.         beq     yap000
  229.         GETDIR  #0,drvbuf       ;If not, reset current drive to AUTO folder
  230.         CHDIR   autobf          ;  and look again.
  231.         SFIRST  attrib,fname
  232.         move.l  D0,D4
  233.         CHDIR   drvbuf
  234.         tst     D4
  235.         beq     yap000
  236.         PRINTLINE error1
  237.         bra     yap060          ;NOW CHECK FILENAME FOR SIZE OF PRINTER BUFFER
  238. yap000: moveq   #34,D0          ;Set up index into DTA for filename
  239.         moveq   #3,D1           ;Set up counter
  240.         moveq   #0,D3
  241.         moveq   #0,D5           ;This register will act as a flag for deleting
  242. yap010: moveq   #0,D2           ;  preceeding zero's
  243.         move.b  (A5,D0.w),D2    ;Start with the 4th character of the filename
  244.         cmpi.b  #'9',D2         ;Test to see if it is a number
  245.         bgt     yap050          ;Exit loop if not
  246.         cmpi.b  #'0',D2
  247.         blt     yap050
  248.         beq     yap020
  249.         moveq   #-1,D5
  250.         bra     yap030
  251. yap020: tst.w   D5
  252.         beq     yap040          ;Do not process preceeding zero's
  253. yap030: move.b  D2,(A4)+        ;Save number in buffer to print out later
  254.         subi.w  #$30,D2
  255.         mulu    #10,D3
  256.         add.w   D2,D3           ;D3 will contain the actual amount of memory
  257. yap040: addq.w  #1,D0           ; needed for the buffer in "K" units
  258.         dbra    D1,yap010
  259. yap050: cmpi.w  #0,D3
  260.         bne     yap070
  261.         PRINTLINE error2        ;No size of buffer in Program Name
  262. yap060  moveq   #32,D3          ;Use default Printer Buffer size of
  263.         move.w  #$3332,(A4)+    ;  32K
  264. yap070: move.b  #0,(A4)+
  265. yap080: move.l  D3,D5
  266.         moveq   #10,D0
  267.         lsl.l   D0,D5
  268.         add.l   D6,D5
  269.         cmp.l   D5,D7           ;Check to see if we have enough memory for
  270.         bgt     yap090          ;  requested PRINTER Spooler
  271.         PRINTLINE error3
  272.         PRINTLINE buflen        ;No, then abort set up
  273.         PRINTLINE error4
  274.         bsr     wte
  275.         TERM
  276. yap090: KBSHIFT #-1             ;Finally, check to see if user wants to
  277.         andi.w  #$6F,D0         ;  abort installation by holding down
  278.         beq     yap100          ;  either shift key, or control key,
  279.         PRINTLINE error6        ;  or alt key!
  280.         bsr     wte
  281.         TERM
  282. yap100: PRINTLINE mess01        ;Announce size of Printer Spooler set up
  283.         PRINTLINE buflen
  284.         PRINTLINE mess02
  285.         bsr     wte
  286.         moveq   #10,D0          ;Calculate total amount of printer buffer
  287.         lsl.l   D0,D3           ;  available to use
  288.         move.l  #ypsend,D0      ;Add in addition program space that will only
  289.         sub.l   #ypstrm,D0      ;  be used once!
  290.         add.l   D0,D3
  291.         move.l  D3,length       ;Save length of Printer Spooler needed
  292.         JDISINT #0              ;Disable Centronic Busy Signal Interrupt
  293.         bsr     go_sup          ;Go to SUPER Mode to make sure that...
  294.         lea     MFP,A1          ;  the proper edge is set for Centronics
  295.         bclr    #0,aer(A1)      ;busy signal interrupts!
  296.         bsr     go_use          ;Return to user mode
  297.         MFPINT  timer,#0        ;Set up Centronics Interrupt
  298.         SETEXEC newtrp,#trap13/4;Set up link to Trap #13
  299.         move.l  D0,trpsve
  300.         clr     -(sp)           ;Save needed buffer size
  301.         move.l  D5,-(sp)        ;and return
  302.         move    #keep,-(sp)
  303.         trap    #gemdos
  304.         TERM
  305. wte:    moveq   #10,D1          ;Routine to wait a bit to see messages
  306. wte10:  moveq   #-1,D0
  307. wte20:  dbra    D0,wte20
  308.         dbra    D1,wte10
  309.         rts
  310. go_sup: clr.l   -(sp)           ;Routine to enter SUPER mode, leaving return
  311. go_s10: move.w  #$20,-(sp)      ;  stack pointer in D0
  312.         trap    #GEMDOS
  313.         addq.l  #6,sp
  314.         rts
  315. go_use: move.l  D0,-(sp)        ;Routine to enter USER mode
  316.         bra     go_s10
  317. ;
  318. ; Data Segment - volatile
  319. ;
  320. attrib: dc.w    0
  321. autobf: dc.b    '\AUTO\',0
  322. fname:  dc.b    'YAPS*.PRG',0
  323. tline:  dc.b    13,10,'"YET  ANOTHER  PRINTER  SPOOLER"',13,10
  324.         dc.b    '(Centronics Busy Signal Version)',13,10
  325.         dc.b    '     written by Phillip R. Poulos',13,10,10,0
  326. error1: dc.b    7,'** Original Program Name Not Found **',13,10,10,0
  327. error2: dc.b    7,'** Size For  Printer Spooler **',13,10
  328.         dc.b    '** Not Found In Program Name **',13,10,10,0
  329. error3: dc.b    7,'** Not Enough   MEMORY   Available **',13,10
  330.         dc.b    '**To Set Up A ',0
  331. error4: dc.b    'K Printer Spooler **',13,10
  332.         dc.b    '**       Installation Aborted!     **',13,10,0
  333. error5: dc.b    7,'**   YAPS is already running...   **',13,10
  334.         dc.b    '**      Installation Aborted!     **',13,10,10
  335.         dc.b    'Clear the printer spooler (Y or N)? ',0
  336. error6: dc.b    7,'** So you wish to abort installation! **',13,10
  337.         dc.b      '** See if I do you any favors soon... **',13,10,0
  338. mess01: dc.b    'Setting up a ',0
  339. mess02: dc.b    'K Printer Spooler!',13,10,0
  340.         align.w
  341. ;
  342. ; BSS Segment - volatile
  343. ;
  344. buflen: ds.b    10
  345. drvbuf: ds.b    64
  346. ypsend: end
  347.  
  348.  
  349.  
  350.